@meissa_a/meissa 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +350 -0
- package/dist/apps/app-generator.d.ts +30 -0
- package/dist/apps/index.d.ts +25 -0
- package/dist/apps/postmessage.d.ts +24 -0
- package/dist/apps/template.d.ts +10 -0
- package/dist/apps/types.d.ts +107 -0
- package/dist/apps.cjs +687 -0
- package/dist/apps.js +645 -0
- package/dist/client/component.d.ts +17 -0
- package/dist/client/content.d.ts +12 -0
- package/dist/client/index.d.ts +7 -0
- package/dist/client/patch.d.ts +6 -0
- package/dist/client/renderer.d.ts +43 -0
- package/dist/client/types.d.ts +52 -0
- package/dist/client.cjs +3558 -0
- package/dist/client.js +3524 -0
- package/dist/renderer/ComponentRenderer.d.ts +11 -0
- package/dist/renderer/MeissaRenderer.d.ts +8 -0
- package/dist/renderer/components/Alert.d.ts +2 -0
- package/dist/renderer/components/Badge.d.ts +2 -0
- package/dist/renderer/components/Btn.d.ts +2 -0
- package/dist/renderer/components/Card.d.ts +2 -0
- package/dist/renderer/components/Chart.d.ts +2 -0
- package/dist/renderer/components/Code.d.ts +2 -0
- package/dist/renderer/components/Col.d.ts +2 -0
- package/dist/renderer/components/Divider.d.ts +2 -0
- package/dist/renderer/components/Form.d.ts +2 -0
- package/dist/renderer/components/Grid.d.ts +2 -0
- package/dist/renderer/components/Heading.d.ts +2 -0
- package/dist/renderer/components/Img.d.ts +2 -0
- package/dist/renderer/components/Input.d.ts +2 -0
- package/dist/renderer/components/List.d.ts +2 -0
- package/dist/renderer/components/Progress.d.ts +2 -0
- package/dist/renderer/components/Row.d.ts +2 -0
- package/dist/renderer/components/Select.d.ts +2 -0
- package/dist/renderer/components/Split.d.ts +2 -0
- package/dist/renderer/components/Stat.d.ts +2 -0
- package/dist/renderer/components/Table.d.ts +2 -0
- package/dist/renderer/components/Tabs.d.ts +2 -0
- package/dist/renderer/components/Text.d.ts +2 -0
- package/dist/renderer/components/index.d.ts +2 -0
- package/dist/renderer/context/ActionContext.d.ts +3 -0
- package/dist/renderer/context/DataContext.d.ts +3 -0
- package/dist/renderer/context/FormContext.d.ts +10 -0
- package/dist/renderer/core/binder.d.ts +17 -0
- package/dist/renderer/core/evaluator.d.ts +13 -0
- package/dist/renderer/core/iterator.d.ts +10 -0
- package/dist/renderer/core/normalizer.d.ts +5 -0
- package/dist/renderer/core/parser.d.ts +8 -0
- package/dist/renderer/core/resolver.d.ts +6 -0
- package/dist/renderer/core/types.d.ts +68 -0
- package/dist/renderer/index.d.ts +7 -0
- package/dist/renderer/utils/cn.d.ts +2 -0
- package/dist/renderer/utils/filters.d.ts +8 -0
- package/dist/renderer/utils/sanitize.d.ts +9 -0
- package/dist/renderer.cjs +3273 -0
- package/dist/renderer.js +3239 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/markdown.d.ts +9 -0
- package/dist/server/server.d.ts +39 -0
- package/dist/server/types.d.ts +56 -0
- package/dist/server/validator.d.ts +5 -0
- package/dist/server.cjs +345 -0
- package/dist/server.js +303 -0
- package/package.json +84 -0
package/README.md
ADDED
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# @meissa_a/meissa
|
|
2
|
+
|
|
3
|
+
Token-efficient generative UI for MCP, in one package with four entry points:
|
|
4
|
+
|
|
5
|
+
| Import | What it is |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `@meissa_a/meissa/renderer` | React component library — renders interactive UI from declarative JSON schemas |
|
|
8
|
+
| `@meissa_a/meissa/client` | Client SDK for rendering Meissa content in MCP hosts (React) |
|
|
9
|
+
| `@meissa_a/meissa/server` | Server SDK for returning Meissa UI from MCP tools (zero runtime deps) |
|
|
10
|
+
| `@meissa_a/meissa/apps` | MCP Apps adapter — serves Meissa UI as sandboxed HTML iframes |
|
|
11
|
+
|
|
12
|
+
Define your UI as compact tuples or objects, bind live data, and let the renderer handle the rest.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# npm
|
|
18
|
+
npm install @meissa_a/meissa react react-dom
|
|
19
|
+
|
|
20
|
+
# pnpm
|
|
21
|
+
pnpm add @meissa_a/meissa react react-dom
|
|
22
|
+
|
|
23
|
+
# bun
|
|
24
|
+
bun add @meissa_a/meissa react react-dom
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
> `react` / `react-dom` are optional peers — only needed for the `renderer` and `client` entry points.
|
|
28
|
+
|
|
29
|
+
### Requirements
|
|
30
|
+
|
|
31
|
+
- React 19+
|
|
32
|
+
- Tailwind CSS v4 (for styling)
|
|
33
|
+
|
|
34
|
+
### Tailwind Setup
|
|
35
|
+
|
|
36
|
+
Add the renderer's source to your Tailwind config so its classes are included:
|
|
37
|
+
|
|
38
|
+
```css
|
|
39
|
+
/* app.css */
|
|
40
|
+
@import "tailwindcss";
|
|
41
|
+
@source "../node_modules/@meissa_a/meissa/dist/**/*.js";
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Quick Start
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { MeissaRenderer } from "@meissa_a/meissa/renderer";
|
|
48
|
+
|
|
49
|
+
const schema = [
|
|
50
|
+
["heading", "Hello World"],
|
|
51
|
+
["text", "This is rendered from JSON."],
|
|
52
|
+
["btn", { label: "Click me", action: "greet" }],
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
function App() {
|
|
56
|
+
return (
|
|
57
|
+
<MeissaRenderer
|
|
58
|
+
schema={schema}
|
|
59
|
+
data={{ user: "Alice" }}
|
|
60
|
+
onAction={(name, args) => console.log(name, args)}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## API
|
|
67
|
+
|
|
68
|
+
### `<MeissaRenderer>`
|
|
69
|
+
|
|
70
|
+
The main entry point. Parses the schema, resolves data bindings, and renders the component tree.
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
<MeissaRenderer
|
|
74
|
+
schema={schema} // Meissa JSON schema (required)
|
|
75
|
+
data={data} // Data context for {{bindings}}
|
|
76
|
+
theme={theme} // Theme overrides
|
|
77
|
+
onAction={handler} // Action callback (button clicks, form submits)
|
|
78
|
+
onNavigate={handler} // Navigation callback
|
|
79
|
+
className="..." // Container className
|
|
80
|
+
/>
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
| Prop | Type | Description |
|
|
84
|
+
|------|------|-------------|
|
|
85
|
+
| `schema` | `MeissaInput` | JSON schema — array of tuples, single node, or full document |
|
|
86
|
+
| `data` | `Record<string, unknown>` | Data context for resolving `{{bindings}}` |
|
|
87
|
+
| `theme` | `MeissaTheme` | Theme overrides (colors, radius, density, font) |
|
|
88
|
+
| `onAction` | `(name: string, args?: Record<string, unknown>) => void` | Called when actions fire (button clicks, form submissions) |
|
|
89
|
+
| `onNavigate` | `(uri: string) => void` | Called for navigation events |
|
|
90
|
+
| `className` | `string` | CSS class on the container element |
|
|
91
|
+
|
|
92
|
+
## Schema Format
|
|
93
|
+
|
|
94
|
+
Schemas use a compact tuple syntax: `[type, primaryProp?, children?]`
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
["text", "Hello"]
|
|
98
|
+
["btn", { "label": "Submit", "variant": "primary" }]
|
|
99
|
+
["row", { "gap": 4 }, [["btn", "A"], ["btn", "B"]]]
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Or verbose object form:
|
|
103
|
+
|
|
104
|
+
```json
|
|
105
|
+
{ "type": "text", "content": "Hello", "bold": true }
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Full Document
|
|
109
|
+
|
|
110
|
+
```json
|
|
111
|
+
{
|
|
112
|
+
"v": 1,
|
|
113
|
+
"data": { "user": "Alice", "count": 42 },
|
|
114
|
+
"theme": { "radius": "md", "colors": { "primary": "#6366f1" } },
|
|
115
|
+
"ui": [
|
|
116
|
+
["heading", "Dashboard"],
|
|
117
|
+
["stat", { "label": "Users", "value": "{{count}}" }]
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Components
|
|
123
|
+
|
|
124
|
+
22 built-in components covering layout, content, data display, and interactivity:
|
|
125
|
+
|
|
126
|
+
### Layout
|
|
127
|
+
|
|
128
|
+
| Component | Shorthand | Description |
|
|
129
|
+
|-----------|-----------|-------------|
|
|
130
|
+
| `row` | `["row", [children]]` | Horizontal flex container |
|
|
131
|
+
| `col` | `["col", [children]]` | Vertical flex container |
|
|
132
|
+
| `grid` | `["grid", { cols: 3 }, [children]]` | CSS grid |
|
|
133
|
+
| `split` | `["split", { ratio: "1/3" }, [left, right]]` | Two-panel layout |
|
|
134
|
+
| `divider` | `["divider"]` or `["divider", "Section"]` | Horizontal rule with optional label |
|
|
135
|
+
|
|
136
|
+
### Content
|
|
137
|
+
|
|
138
|
+
| Component | Shorthand | Description |
|
|
139
|
+
|-----------|-----------|-------------|
|
|
140
|
+
| `text` | `["text", "Hello"]` | Text content with variants |
|
|
141
|
+
| `heading` | `["heading", "Title"]` | h1-h6 heading |
|
|
142
|
+
| `code` | `["code", "const x = 1"]` | Code block or inline code |
|
|
143
|
+
| `img` | `["img", "url"]` | Image |
|
|
144
|
+
| `badge` | `["badge", "New"]` | Status indicator |
|
|
145
|
+
| `alert` | `["alert", "Warning message"]` | Notification banner |
|
|
146
|
+
| `progress` | `["progress", { value: 75 }]` | Progress bar |
|
|
147
|
+
|
|
148
|
+
### Data Display
|
|
149
|
+
|
|
150
|
+
| Component | Shorthand | Description |
|
|
151
|
+
|-----------|-----------|-------------|
|
|
152
|
+
| `stat` | `["stat", { label: "Revenue", value: "{{rev}}" }]` | KPI metric |
|
|
153
|
+
| `list` | `["list", ["one", "two", "three"]]` | Ordered/unordered list |
|
|
154
|
+
| `table` | `["table", { data: "{{rows}}" }]` | Data table with sorting & pagination |
|
|
155
|
+
| `chart` | `["chart", { data: "{{sales}}", type: "bar" }]` | Recharts-powered chart |
|
|
156
|
+
|
|
157
|
+
### Interactive
|
|
158
|
+
|
|
159
|
+
| Component | Shorthand | Description |
|
|
160
|
+
|-----------|-----------|-------------|
|
|
161
|
+
| `btn` | `["btn", "Click me"]` | Button with action dispatch |
|
|
162
|
+
| `input` | `["input", { name: "email", type: "email" }]` | Text input |
|
|
163
|
+
| `select` | `["select", { name: "role", options: [...] }]` | Dropdown select |
|
|
164
|
+
| `form` | `["form", { submit: "save" }, [children]]` | Form container |
|
|
165
|
+
| `card` | `["card", "Title", [children]]` | Card container |
|
|
166
|
+
| `tabs` | `["tabs", { items: {...} }]` | Tabbed panels |
|
|
167
|
+
|
|
168
|
+
## Data Binding
|
|
169
|
+
|
|
170
|
+
Use `{{path}}` syntax to bind data into any string prop:
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
["text", "Hello, {{user.name}}!"]
|
|
174
|
+
["stat", { "value": "{{metrics.revenue}}", "label": "Revenue" }]
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Filters
|
|
178
|
+
|
|
179
|
+
Chain filters with `|`:
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
["text", "{{price | currency}}"]
|
|
183
|
+
["text", "{{name | uppercase}}"]
|
|
184
|
+
["text", "{{description | truncate}}"]
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Built-in filters: `currency`, `percent`, `number`, `uppercase`, `lowercase`, `truncate`, `relative`, `date`, `default`.
|
|
188
|
+
|
|
189
|
+
### Comparisons
|
|
190
|
+
|
|
191
|
+
Expressions resolve to booleans:
|
|
192
|
+
|
|
193
|
+
```json
|
|
194
|
+
["text", { "content": "Premium", "if": "{{plan == 'pro'}}" }]
|
|
195
|
+
["alert", { "content": "Low stock", "if": "{{count < 10}}" }]
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Conditionals
|
|
199
|
+
|
|
200
|
+
### `if` — Remove from DOM
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
["text", { "content": "Admin only", "if": "{{isAdmin}}" }]
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### `show` — Toggle visibility (keeps DOM element)
|
|
207
|
+
|
|
208
|
+
```json
|
|
209
|
+
["text", { "content": "Loading...", "show": "{{loading}}" }]
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### `switch` — Multi-branch
|
|
213
|
+
|
|
214
|
+
```json
|
|
215
|
+
["switch", "{{status}}", {
|
|
216
|
+
"active": ["badge", { "content": "Active", "variant": "success" }],
|
|
217
|
+
"inactive": ["badge", { "content": "Inactive", "variant": "default" }],
|
|
218
|
+
"_": ["badge", "Unknown"]
|
|
219
|
+
}]
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Iteration
|
|
223
|
+
|
|
224
|
+
Loop over arrays with `each`:
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
["each", "{{users}}", ["card", "{{$.name}}", [
|
|
228
|
+
["text", "{{$.email}}"]
|
|
229
|
+
]]]
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Context variables inside each:
|
|
233
|
+
- `$` — current item
|
|
234
|
+
- `$i` — index (0-based)
|
|
235
|
+
- `$first` — `true` for first item
|
|
236
|
+
- `$last` — `true` for last item
|
|
237
|
+
|
|
238
|
+
## Theming
|
|
239
|
+
|
|
240
|
+
Pass a `theme` prop or include `theme` in the document:
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
<MeissaRenderer
|
|
244
|
+
schema={schema}
|
|
245
|
+
theme={{
|
|
246
|
+
radius: "lg",
|
|
247
|
+
density: "relaxed",
|
|
248
|
+
font: "Inter, sans-serif",
|
|
249
|
+
colors: {
|
|
250
|
+
primary: "#6366f1",
|
|
251
|
+
destructive: "#ef4444",
|
|
252
|
+
success: "#10b981",
|
|
253
|
+
bg: "#ffffff",
|
|
254
|
+
fg: "#0f172a",
|
|
255
|
+
muted: "#64748b",
|
|
256
|
+
border: "#e2e8f0",
|
|
257
|
+
},
|
|
258
|
+
}}
|
|
259
|
+
/>
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## Actions
|
|
263
|
+
|
|
264
|
+
Components dispatch actions via `onAction`:
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
<MeissaRenderer
|
|
268
|
+
schema={[
|
|
269
|
+
["btn", { "label": "Delete", "action": "deleteItem", "args": { "id": 42 } }],
|
|
270
|
+
["form", { "submit": "saveUser" }, [
|
|
271
|
+
["input", { "name": "email", "type": "email" }],
|
|
272
|
+
["btn", { "label": "Save", "submit": true }]
|
|
273
|
+
]]
|
|
274
|
+
]}
|
|
275
|
+
onAction={(action, args) => {
|
|
276
|
+
// action: "deleteItem" | "saveUser"
|
|
277
|
+
// args: { id: 42 } | { email: "..." }
|
|
278
|
+
}}
|
|
279
|
+
/>
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Advanced Usage
|
|
283
|
+
|
|
284
|
+
### Custom Component Registry
|
|
285
|
+
|
|
286
|
+
```tsx
|
|
287
|
+
import { COMPONENT_REGISTRY, ComponentRenderer } from "@meissa_a/meissa/renderer";
|
|
288
|
+
|
|
289
|
+
// Add a custom component
|
|
290
|
+
COMPONENT_REGISTRY["my-widget"] = ({ node, children }) => (
|
|
291
|
+
<div className="my-widget">{children}</div>
|
|
292
|
+
);
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### Using Core Pipeline Directly
|
|
296
|
+
|
|
297
|
+
```tsx
|
|
298
|
+
import { parse, normalize, resolveBindings } from "@meissa_a/meissa/renderer";
|
|
299
|
+
|
|
300
|
+
// Parse raw schema
|
|
301
|
+
const doc = parse(rawJson);
|
|
302
|
+
|
|
303
|
+
// Normalize a single tuple
|
|
304
|
+
const node = normalize(["btn", { label: "Click", variant: "ghost" }]);
|
|
305
|
+
|
|
306
|
+
// Resolve bindings manually
|
|
307
|
+
const value = resolveBindings("{{user.name}}", { user: { name: "Alice" } });
|
|
308
|
+
// → "Alice"
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## TypeScript
|
|
312
|
+
|
|
313
|
+
All types are exported:
|
|
314
|
+
|
|
315
|
+
```tsx
|
|
316
|
+
import type {
|
|
317
|
+
MeissaRendererProps,
|
|
318
|
+
MeissaInput,
|
|
319
|
+
MeissaDocument,
|
|
320
|
+
NormalizedNode,
|
|
321
|
+
MeissaTheme,
|
|
322
|
+
ComponentProps,
|
|
323
|
+
MeissaComponent,
|
|
324
|
+
ActionHandler,
|
|
325
|
+
NavigateHandler,
|
|
326
|
+
} from "@meissa_a/meissa/renderer";
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Development
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
# Install dependencies
|
|
333
|
+
bun install
|
|
334
|
+
|
|
335
|
+
# Run tests
|
|
336
|
+
bun test
|
|
337
|
+
|
|
338
|
+
# Type check
|
|
339
|
+
bun run typecheck
|
|
340
|
+
|
|
341
|
+
# Build (ESM + CJS)
|
|
342
|
+
bun run build
|
|
343
|
+
|
|
344
|
+
# Watch mode
|
|
345
|
+
bun run dev
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## License
|
|
349
|
+
|
|
350
|
+
MIT
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { MeissaSchema, MeissaAppOptions, MeissaAppResult } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Creates a self-contained Meissa app as an HTML string.
|
|
4
|
+
*
|
|
5
|
+
* This is the main entry point for the MCP Apps adapter. It takes a Meissa
|
|
6
|
+
* schema and options, and returns a complete HTML page that can be served
|
|
7
|
+
* as a sandboxed iframe resource in the MCP Apps protocol.
|
|
8
|
+
*
|
|
9
|
+
* @param schema - Meissa schema array describing the UI
|
|
10
|
+
* @param options - Optional configuration (theme, title, dimensions)
|
|
11
|
+
* @returns Object with `content` (HTML string) and `mimeType` ("text/html")
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* import { createMeissaApp } from "@meissa_a/meissa/apps";
|
|
16
|
+
*
|
|
17
|
+
* const result = createMeissaApp(
|
|
18
|
+
* [
|
|
19
|
+
* ["heading", "Dashboard"],
|
|
20
|
+
* ["text", "Welcome, {{user.name}}!"],
|
|
21
|
+
* ["btn", { label: "Refresh", action: "refresh" }],
|
|
22
|
+
* ],
|
|
23
|
+
* { title: "My Dashboard", theme: { primary: "#3b82f6" } }
|
|
24
|
+
* );
|
|
25
|
+
*
|
|
26
|
+
* // result.content -> complete HTML string
|
|
27
|
+
* // result.mimeType -> "text/html"
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export declare function createMeissaApp(schema: MeissaSchema, options?: MeissaAppOptions): MeissaAppResult;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @meissa_a/meissa/apps
|
|
3
|
+
*
|
|
4
|
+
* MCP Apps adapter for serving Meissa UI as sandboxed HTML iframes.
|
|
5
|
+
*
|
|
6
|
+
* This package generates self-contained HTML pages that embed the Meissa
|
|
7
|
+
* renderer for use with the MCP Apps protocol. The generated HTML pages
|
|
8
|
+
* communicate with the host via postMessage.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { createMeissaApp } from "@meissa_a/meissa/apps";
|
|
13
|
+
*
|
|
14
|
+
* // In an MCP server resource handler:
|
|
15
|
+
* const result = createMeissaApp(
|
|
16
|
+
* [["heading", "Hello"], ["text", "World"]],
|
|
17
|
+
* { title: "My App" }
|
|
18
|
+
* );
|
|
19
|
+
* // result.content is a complete HTML string
|
|
20
|
+
* // result.mimeType is "text/html"
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export { createMeissaApp } from "./app-generator.js";
|
|
24
|
+
export type { MeissaSchema, MeissaSchemaElement, MeissaTheme, MeissaAppOptions, MeissaAppResult, MeissaOutgoingMessage, MeissaIncomingMessage, MeissaActionMessage, MeissaNavigateMessage, MeissaReadyMessage, MeissaResizeMessage, MeissaDataMessage, MeissaPatchMessage, MeissaUpdateMessage, MeissaActionResponseMessage, MeissaJsonPatch, } from "./types.js";
|
|
25
|
+
export { MESSAGE_TYPES } from "./postmessage.js";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PostMessage protocol definitions for Meissa MCP Apps.
|
|
3
|
+
*
|
|
4
|
+
* This module defines the message types and constants used for
|
|
5
|
+
* communication between the sandboxed iframe and the host application.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Message type constants for the postMessage protocol.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MESSAGE_TYPES: {
|
|
11
|
+
readonly ACTION: "meissa:action";
|
|
12
|
+
readonly NAVIGATE: "meissa:navigate";
|
|
13
|
+
readonly READY: "meissa:ready";
|
|
14
|
+
readonly RESIZE: "meissa:resize";
|
|
15
|
+
readonly DATA: "meissa:data";
|
|
16
|
+
readonly PATCH: "meissa:patch";
|
|
17
|
+
readonly UPDATE: "meissa:update";
|
|
18
|
+
readonly ACTION_RESPONSE: "meissa:action-response";
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Returns the inline JavaScript code for the postMessage handler.
|
|
22
|
+
* This is injected into the HTML template.
|
|
23
|
+
*/
|
|
24
|
+
export declare function getPostMessageHandlerCode(): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { MeissaSchema, MeissaTheme } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Generate a complete self-contained HTML page from a Meissa schema.
|
|
4
|
+
*/
|
|
5
|
+
export declare function generateHtml(schema: MeissaSchema, options?: {
|
|
6
|
+
title?: string;
|
|
7
|
+
theme?: MeissaTheme;
|
|
8
|
+
width?: string;
|
|
9
|
+
height?: string;
|
|
10
|
+
}): string;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Meissa schema element — a tuple of [componentType, ...args]
|
|
3
|
+
* Examples:
|
|
4
|
+
* ["heading", "Dashboard"]
|
|
5
|
+
* ["btn", { label: "Click me", action: "onClick" }]
|
|
6
|
+
* ["row", [...children]]
|
|
7
|
+
*/
|
|
8
|
+
export type MeissaSchemaElement = [string, ...unknown[]];
|
|
9
|
+
/**
|
|
10
|
+
* A Meissa schema is an array of schema elements.
|
|
11
|
+
*/
|
|
12
|
+
export type MeissaSchema = MeissaSchemaElement[];
|
|
13
|
+
/**
|
|
14
|
+
* Theme configuration for the Meissa renderer.
|
|
15
|
+
*/
|
|
16
|
+
export interface MeissaTheme {
|
|
17
|
+
/** Background color */
|
|
18
|
+
bg?: string;
|
|
19
|
+
/** Foreground/text color */
|
|
20
|
+
fg?: string;
|
|
21
|
+
/** Primary accent color */
|
|
22
|
+
primary?: string;
|
|
23
|
+
/** Secondary accent color */
|
|
24
|
+
secondary?: string;
|
|
25
|
+
/** Muted/subtle color */
|
|
26
|
+
muted?: string;
|
|
27
|
+
/** Border color */
|
|
28
|
+
border?: string;
|
|
29
|
+
/** Error/danger color */
|
|
30
|
+
error?: string;
|
|
31
|
+
/** Success color */
|
|
32
|
+
success?: string;
|
|
33
|
+
/** Warning color */
|
|
34
|
+
warning?: string;
|
|
35
|
+
/** Border radius (e.g., "0.5rem") */
|
|
36
|
+
radius?: string;
|
|
37
|
+
/** Font family */
|
|
38
|
+
font?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Options for createMeissaApp.
|
|
42
|
+
*/
|
|
43
|
+
export interface MeissaAppOptions {
|
|
44
|
+
/** Theme configuration */
|
|
45
|
+
theme?: MeissaTheme;
|
|
46
|
+
/** HTML page title */
|
|
47
|
+
title?: string;
|
|
48
|
+
/** Width hint for iframe (e.g., "800px", "100%") */
|
|
49
|
+
width?: string;
|
|
50
|
+
/** Height hint for iframe (e.g., "600px", "100%") */
|
|
51
|
+
height?: string;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The result returned by createMeissaApp.
|
|
55
|
+
*/
|
|
56
|
+
export interface MeissaAppResult {
|
|
57
|
+
/** The complete self-contained HTML string */
|
|
58
|
+
content: string;
|
|
59
|
+
/** MIME type — always "text/html" */
|
|
60
|
+
mimeType: "text/html";
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Outgoing messages (iframe -> host).
|
|
64
|
+
*/
|
|
65
|
+
export type MeissaOutgoingMessage = MeissaActionMessage | MeissaNavigateMessage | MeissaReadyMessage | MeissaResizeMessage;
|
|
66
|
+
export interface MeissaActionMessage {
|
|
67
|
+
type: "meissa:action";
|
|
68
|
+
action: string;
|
|
69
|
+
args: Record<string, unknown>;
|
|
70
|
+
}
|
|
71
|
+
export interface MeissaNavigateMessage {
|
|
72
|
+
type: "meissa:navigate";
|
|
73
|
+
uri: string;
|
|
74
|
+
}
|
|
75
|
+
export interface MeissaReadyMessage {
|
|
76
|
+
type: "meissa:ready";
|
|
77
|
+
}
|
|
78
|
+
export interface MeissaResizeMessage {
|
|
79
|
+
type: "meissa:resize";
|
|
80
|
+
height: number;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Incoming messages (host -> iframe).
|
|
84
|
+
*/
|
|
85
|
+
export type MeissaIncomingMessage = MeissaDataMessage | MeissaPatchMessage | MeissaUpdateMessage | MeissaActionResponseMessage;
|
|
86
|
+
export interface MeissaDataMessage {
|
|
87
|
+
type: "meissa:data";
|
|
88
|
+
data: Record<string, unknown>;
|
|
89
|
+
}
|
|
90
|
+
export interface MeissaPatchMessage {
|
|
91
|
+
type: "meissa:patch";
|
|
92
|
+
patches: MeissaJsonPatch[];
|
|
93
|
+
}
|
|
94
|
+
export interface MeissaUpdateMessage {
|
|
95
|
+
type: "meissa:update";
|
|
96
|
+
data: Record<string, unknown>;
|
|
97
|
+
}
|
|
98
|
+
export interface MeissaActionResponseMessage {
|
|
99
|
+
type: "meissa:action-response";
|
|
100
|
+
result: unknown;
|
|
101
|
+
}
|
|
102
|
+
export interface MeissaJsonPatch {
|
|
103
|
+
op: "add" | "remove" | "replace" | "move" | "copy" | "test";
|
|
104
|
+
path: string;
|
|
105
|
+
value?: unknown;
|
|
106
|
+
from?: string;
|
|
107
|
+
}
|